package com.example.springboot.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot.common.Result;
import com.example.springboot.entity.Files;
import com.example.springboot.mapper.FileMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

@RequestMapping("/file")
@RestController
public class FileController {

    @Value("${files.upload.path}")
    private String fileUploadPath;

    @Value("${server.ip}")
    private String serverIp;
    @Resource
    private FileMapper fileMapper;

    /**
     * 文件上传接口
     * @param file  前端传进来的文件
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename=file.getOriginalFilename();     //文件初始名称
        String type= FileUtil.extName(originalFilename);       //文件类型
        long size = file.getSize();                            //文件大小
        //先存储到磁盘
        File file1 = new File(fileUploadPath);
        if (!file1.exists()){   //先判断文件是否存在
            file1.mkdirs();
        }
        //定义一个文件唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        String fileUUID = uuid + StrUtil.DOT + type;

        File uploadFile = new File(fileUploadPath + fileUUID);
        String md5;
        String url;
        //把获取的文件存储到磁盘中
        file.transferTo(uploadFile);
        //获取文件MD5
        md5 = SecureUtil.md5(uploadFile);
        //从数据库中查询是否存在相同的记录
        Files files = getFileMd5(md5);
        if (files!=null){
            url=files.getUrl();
            //文件已存在 删除刚上传的文件
            uploadFile.delete();
        }else {
            url="http://"+ serverIp +":7992/file/"+fileUUID;
        }

        //存储数据库
        Files file2 = new Files();;
        file2.setName(originalFilename);
        file2.setType(type);
        file2.setSize(size/1024 );
        file2.setUrl(url);
        file2.setMd5(md5);
        fileMapper.insert(file2);

        return url;

    }

    /**
     * 文件下载
     * @param fileUUID
     * @param httpServletResponse
     * @throws IOException
     */
    @GetMapping("/{fileUUID}")
        public void  download(@PathVariable String fileUUID, HttpServletResponse httpServletResponse) throws IOException {
        //根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath + fileUUID);
        //设置输出流格式
        ServletOutputStream os = httpServletResponse.getOutputStream();
        httpServletResponse.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        httpServletResponse.setContentType("application/octet-stream");
        //读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }

    /**
     * 通过文件的md5查询文件
     * @param md5
     * @return
     */
    private Files getFileMd5(String md5){

        //查询文件的md5是否存在
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5",md5);
        List<Files>list =fileMapper.selectList(queryWrapper);
        return  list.size()==0?null:list.get(0);
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {
        return Result.success(fileMapper.deleteById(id));
    }

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @PostMapping("batch")
    public Result delete(@RequestBody List<Integer> ids){
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id",ids);
        for (Files files : fileMapper.selectList(queryWrapper)) {
            fileMapper.deleteById(files);
        }
        return Result.success();
    }
    @PostMapping("/update")
    public Result save(@RequestBody Files files) {
        //更新
        return Result.success(fileMapper.updateById(files));
    }


    /**
     * 分页查询
     * @param pageNum
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    //分页查询
    public Result findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           @RequestParam(defaultValue = "")  String name) {
        IPage<Files> page=new Page(pageNum,pageSize);
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();

        if (!"".equals(name)){
            queryWrapper.like("name",name);
        }
        return Result.success(fileMapper.selectPage(page, queryWrapper));
    }

}
